#pragma once

#include <iostream>
#include <string>
#include <cassert>
#include <pthread.h>

class ThreadData
{
public:
    // 通过指定线程名称和线程函数参数，来创建线程数据类
    ThreadData(const std::string name, void *args)
        : _name(name)
        , _args(args)
    {  }

    // 获取线程名称
    std::string name()
    {
        return _name;
    }

    // 析构函数
    ~ThreadData()
    { }

    std::string _name;
    void *_args;
};

class Thread
{
    typedef void *(*func_t)(void *);  // 函数指针类型重定义

public:
    // 线程类构造函数 -- 指定线程编号、线程函数、线程函数参数来构造线程类
    Thread(const std::string& name, func_t func, void *args)
        : _name(name)
        , _func(func)
        , _thread_data(name, args)
    { 
        // 创建线程
        pthread_create(&_id, nullptr, _func, (void*)&_thread_data);
    }

    // 线程名称获取函数
    std::string name()
    {
        return _thread_data.name();
    }

    // 析构函数
    ~Thread()
    {
        join();  // 等待线程退出
    }

private:
    // 线程等待函数
    void join()
    {
        int n = pthread_join(_id, nullptr);
        assert(n == 0);
        (void)n;
    }
    
    std::string _name;       // 线程名称
    func_t _func;            // 线程函数指针
    ThreadData _thread_data; // 线程数据
    pthread_t _id;           // 线程id
};